#include <sstream>
#include <iterator>
#include "test_base.hpp"

template <typename T>
class istream_stlrange
{
  std::istream& stream;

public:
  istream_stlrange(std::istream& stream) : stream(stream) {}
  std::istream_iterator<T> begin() const
    { return std::istream_iterator<T>(stream); }
  std::istream_iterator<T> end() const { return std::istream_iterator<T>(); }
};

typedef std::istringstream iss;
typedef istream_stlrange<int> ints;

TEST(InputIteratorAdapter, emptyString_rangeIsEmpty) {
  iss source("");
  auto r = all(ints(source));
  ASSERT_TRUE(r.empty());
}

TEST(InputIteratorAdapter, stringWithoutInt_rangeIsEmpty) {
  iss source("foo");
  auto r = all(ints(source));
  ASSERT_TRUE(r.empty());
}

TEST(InputIteratorAdapter, stringWithInt_rangeIsNotEmpty) {
  iss source("42");
  auto r = all(ints(source));
  ASSERT_FALSE(r.empty());
}

TEST(InputIteratorAdapter, stringWithInt_frontReturnsInt) {
  iss source("42");
  auto r = all(ints(source));
  ASSERT_EQ(42, r.front());
}

TEST(InputIteratorAdapter, stringWithInt_popFrontLeavesEmpty) {
  iss source("42");
  auto r = all(ints(source));
  r.pop_front();
  ASSERT_TRUE(r.empty());
}

TEST(InputIteratorAdapter, stringWithTwoInts_popFrontLeavesNotEmpty) {
  iss source("42 77");
  auto r = all(ints(source));
  r.pop_front();
  ASSERT_FALSE(r.empty());
}

TEST(InputIteratorAdapter, stringWithTwoInts_popFront_frontReturnsSecondInt) {
  iss source("42 77");
  auto r = all(ints(source));
  r.pop_front();
  ASSERT_EQ(77, r.front());
}
